package service

import (
	"context"

	"gitee.com/thewalkers/refactoring-code/model"
)

// EmployeeService acts as a struct for injecting an implementation of EmployeeRepository
// for use in service methods
type EmployeeService struct {
	EmployeeRespository model.EmployeeRespository
}

// EMConfig will hold repository that will eventually be injected into this
// service layer
type EMConfig struct {
	EmployeeRespository model.EmployeeRespository
}

// NewEmployeeService is a factory function for
// initializing a EmployeeService with its repository layer dependencies
func NewEmployeeService(c *EMConfig) model.EmployeeService {
	return &EmployeeService{
		EmployeeRespository: c.EmployeeRespository,
	}
}

// Get return a employee based on their id
func (e *EmployeeService) Get(ctx context.Context, id int64) (*model.Employee, error) {
	employee, err := e.EmployeeRespository.FindByID(ctx, id)

	return employee, err
}

// Create return a employee
func (e *EmployeeService) Create(ctx context.Context, employee *model.Employee) error {
	if err := e.EmployeeRespository.Create(ctx, employee); err != nil {
		return err
	}

	return nil
}

func (e *EmployeeService) Delete(ctx context.Context, id int64) error {
	return e.EmployeeRespository.DeleteByID(ctx, id)
}

func (e *EmployeeService) GetName(ctx context.Context, id int64) (string, error) {
	employee, err := e.EmployeeRespository.FindByID(ctx, id)
	return employee.Name, err
}

func (e *EmployeeService) GetAddress(ctx context.Context, id int64) (string, error) {
	employee, err := e.EmployeeRespository.FindByID(ctx, id)
	return employee.Address, err
}

func (e *EmployeeService) UpdateByID(ctx context.Context, employee *model.Employee) error {
	err := e.EmployeeRespository.UpdateByID(ctx, employee)
	return err
}

func (e *EmployeeService) SetClassification(ctx context.Context, p *model.PaymentClassification) error {
	err := e.EmployeeRespository.SetClassification(ctx, p)
	return err
}

func (e *EmployeeService) SetSchedule(ctx context.Context, p *model.PaymentSchedule) error {
	err := e.EmployeeRespository.SetSchedule(ctx, p)
	return err
}

func (e *EmployeeService) SetMethod(ctx context.Context, p *model.PaymentMethod) error {
	err := e.EmployeeRespository.SetMethod(ctx, p)
	return err
}

func (e *EmployeeService) GetClassification(ctx context.Context, id int64) (*model.PaymentClassification, error) {
	p, err := e.EmployeeRespository.GetClassification(ctx, id)
	return p, err
}

func (e *EmployeeService) GetSchedule(ctx context.Context, id int64) (*model.PaymentSchedule, error) {
	p, err := e.EmployeeRespository.GetSchedule(ctx, id)
	return p, err
}

func (e *EmployeeService) GetMethod(ctx context.Context, id int64) (*model.PaymentMethod, error) {
	p, err := e.EmployeeRespository.GetMethod(ctx, id)
	return p, err
}

func (e *EmployeeService) SetName(ctx context.Context, id int64, name string) error {
	employee := &model.Employee{
		ID:   id,
		Name: name,
	}

	return e.EmployeeRespository.UpdateByID(ctx, employee)
}

func (e *EmployeeService) SetAddress(ctx context.Context, id int64, address string) error {
	employee := &model.Employee{
		ID:      id,
		Address: address,
	}

	return e.EmployeeRespository.UpdateByID(ctx, employee)
}

func (e *EmployeeService) GetAllEmployeeIds(ctx context.Context, offset, limit int64) ([]int64, error) {
	data, err := e.EmployeeRespository.GetEmployeeList(ctx, offset, limit)
	res := make([]int64, len(data))

	for i := 0; i < len(data); i++ {
		res[i] = data[i].ID
	}

	return res, err
}

// TODO:

// IsPayDate(ctx context.Context, dateTime time.Time) bool
// GetPayPeriodStartDate(ctx context.Context, dateTime time.Time) time.Time
// Paycheck(ctx context.Context, p *Paycheck) error
